package com.cse587.xmlloader;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import com.cse587.entities.Country;
import com.cse587.util.Util;

public class XmlLoader {
	private URL url;
	private SAXReader reader;
	private Document document;

	public XmlLoader() {
	}

	private boolean prepare(String stubUrl) {
		boolean status = false;
		try {
			url = new URL(Util.URLROOT + stubUrl);
			reader = new SAXReader();
			if (url.openConnection().getHeaderField(0)
					.equals("HTTP/1.1 200 OK")) {
				document = reader.read(url);
				status = true;
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return status;
	}

	private boolean loadOtherResources(String urlString) {
		boolean status = false;
		try {
			url = new URL(urlString);
			reader = new SAXReader();
			if (url.openConnection().getHeaderField(0)
					.equals("HTTP/1.1 200 OK")) {
				document = reader.read(url);
				status = true;
			}
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return status;
	}

	public List<Country> loadCountries() throws DocumentException, IOException {
		String stubUrl = "allCountries/EN";
		if (prepare(stubUrl)) {
			List<Country> countryList = new ArrayList<Country>();
			List<? extends Node> nodeList = document
					.selectNodes("//Data/self_governing");
			for (Node node : nodeList) {
				Country country = new Country();
				country.setCodeISO3(node.selectSingleNode("codeISO3").getText());
				country.setFullName(node.selectSingleNode("nameListEN")
						.getText());
				countryList.add(country);
			}
			return countryList;
		} else {
			System.out.println(stubUrl + " server response 500");
			return null;
		}

	}

	// maxLat, maxLong, minLat, minLong
	public String loadCoordinates(String iso3Code) throws DocumentException,
			IOException {
		String stubUrl = "countryCoordinates/" + iso3Code;
		if (prepare(stubUrl)) {
			String result = "";
			result += document.selectSingleNode("//Data/hasMaxLatitude")
					.getText() + ",";
			result += document.selectSingleNode("//Data/hasMaxLongitude")
					.getText() + ",";
			result += document.selectSingleNode("//Data/hasMinLatitude")
					.getText() + ",";
			result += document.selectSingleNode("//Data/hasMinLongitude")
					.getText();
			return result;
		} else {
			System.out.println(stubUrl + "server response 500");
			return "";
		}
	}

	// unit:1000 ha, number, year
	public String loadLandArea(String iso3Code) throws NumberFormatException,
			DocumentException, IOException {
		String stubUrl = "countryStatistics/landArea/" + iso3Code + "/EN";
		if (prepare(stubUrl)) {
			Node node = document.selectSingleNode("//Data/landArea");
			String result = node.selectSingleNode("landAreaTotal").getText()
					+ "," + node.selectSingleNode("landAreaYear").getText();
			return result;
		} else {
			System.out.println(stubUrl + " server response 500");
			return "";
		}
	}

	// 1000, number, year
	public String loadPopulation(String iso3Code) throws DocumentException,
			IOException {
		String stubUrl = "countryStatistics/population/" + iso3Code + "/EN";
		if (prepare(stubUrl)) {
			Node node = document.selectSingleNode("//Data/population");
			String result = node.selectSingleNode("populationTotal").getText()
					+ "," + node.selectSingleNode("populationYear").getText();
			return result;
		} else {
			System.out.println(stubUrl + " server response 500");
			return "";
		}
	}

	// millions of US dollars, number, year
	public String loadGDP(String iso3Code) throws DocumentException,
			IOException {
		String stubUrl = "countryStatistics/GDP/" + iso3Code + "/EN";
		String result = new String();
		if (prepare(stubUrl)) {
			Node node = document.selectSingleNode("//Data/GDP");
			if (node.selectSingleNode("GDPTotalInCurrentPrices") != null) {
				result = node.selectSingleNode("GDPTotalInCurrentPrices")
						.getText()
						+ ","
						+ node.selectSingleNode("GDPYear").getText();
			} else {
				System.out.println(stubUrl + ":null");
				result = "";
			}
		} else {
			System.out.println(stubUrl + " server response 500");
			result = "";
		}
		return result;
	}

	// millions of US dollars, number, year
	public String loadHDI(String iso3Code) throws MalformedURLException,
			IOException, DocumentException {
		String stubUrl = "countryStatistics/HDI/" + iso3Code + "/EN";
		String result = new String();
		if (prepare(stubUrl)) {
			Node node = document.selectSingleNode("//Data/HDI");
			if (node.selectSingleNode("Total") != null) {
				result = node.selectSingleNode("Total").getText() + ","
						+ node.selectSingleNode("Year").getText();
			} else {
				System.out.println(stubUrl + ":null");
				result = "";
			}
		} else {
			System.out.println(stubUrl + " server response 500");
			result = "";
		}
		return result;
	}

	// border of one country
	public String loadBorder(String iso3Code) throws DocumentException,
			IOException {
		String stubUrl = "borderWith/" + iso3Code + "/EN";
		// List<CountryBorder> borderList = new ArrayList<CountryBorder>();
		String result = "";
		if (prepare(stubUrl)) {
			List<? extends Node> nodeList = document
					.selectNodes("//Data/self_governing/codeISO3");
			int i = 0;
			for (Node node : nodeList) {
				result += node.getText();
				if (i != nodeList.size() - 1)
					result += ",";
				i++;

			}
		} else {
			System.out.println(stubUrl + " server response 500");
			result = "";
		}
		return result;
	}

	public Map<String, Country> loadDataFromGEO() throws DocumentException,
			IOException {
		Map<String, Country> map = new HashMap<String, Country>();
		if (loadOtherResources(Util.geoCountryURL)) {
			// document = reader.read("geo-allcountries.xml");
			List<? extends Node> nodeList = document
					.selectNodes("/geonames/country");
			for (Node node : nodeList) {
				Country c = new Country();
				String key = node.selectSingleNode("isoAlpha3").getText();
				c.setCodeISO3(key);
				c.setCapital(node.selectSingleNode("capital").getText());
				c.setMaxLat(Double.valueOf(node.selectSingleNode("bBoxNorth")
						.getText()));
				c.setMaxLong(Double.valueOf(node.selectSingleNode("bBoxEast")
						.getText()));
				c.setMinLat(Double.valueOf(node.selectSingleNode("bBoxSouth")
						.getText()));
				c.setMinLong(Double.valueOf(node.selectSingleNode("bBoxWest")
						.getText()));

				map.put(key, c);
			}
		} else {
			System.out.println(Util.geoCountryURL + "server response 500");
			map = null;
		}
		return map;
	}

	public int loadUnCode(String iso3Code) {
		String stubUrl = "countryCodes/UN/" + iso3Code;
		int result = -1;
		if (prepare(stubUrl)) {
			Node node = document.selectSingleNode("//Data/codeUN");
			if (node != null) {
				result = Integer.valueOf(node.getText());
			} else {
				System.out.println(stubUrl + ":null");
			}
		} else {
			System.out.println(stubUrl + " server response 500");
		}
		return result;
	}

	//lat,lng
	public String loadCapitalLatAndLong(String capital) {
		String stubURL = "address=" + capital + "&sensor=true";
		String result = "";
		if (loadOtherResources(Util.gooeleGeoURL+stubURL)) {
			Node node = document.selectSingleNode("//GeocodeResponse/result/geometry/location");
			if( node != null ){
				result += node.selectSingleNode("lat").getText() + ",";
				result += node.selectSingleNode("lng").getText();
				System.out.println(capital + ":" +result);
			}
		}else{
			System.out.println(Util.gooeleGeoURL+stubURL + " server response 500");
		}
		
		return result;
	}

}
